;;;; hacks.lisp
(in-package #:hacks)

;; let's make a boolean value?
(defclass logical-truth ()
	((verity :initarg :true?
					 :reader true?)))

(defun logical-truth (truth-value)
	(cl:make-instance 'logical-truth :true? truth-value))

(defmethod logical-not ((value logical-truth))
	(logical-truth  (not (true? value))))

;; some constants
(defvar *logical-false* (logical-truth nil))
(defvar *logical-true* (logical-truth T))

(defconstant +stack-bottom+ :this-is-the-stack-bottom)

;; stack class wraps a list, we start by pushing the constant stack-bottom onto '()
(defclass stack ()
	((storage :accessor storage
						:initform (cl:list +stack-bottom+))))

(defun make-stack ()
	(cl:make-instance 'stack))

(defmethod empty? ((stack stack))
	(eq +stack-bottom+ (cl:first (storage stack))))

(defmethod stack-pop ((stack stack))
	(if (empty? stack)
			nil
			(cl:let  ((head (cl:first (storage stack))))
				(cl:setf (storage stack) (cl:rest (storage stack)))
				head)))

(defmethod stack-push (value (stack stack))
	(setf (storage stack) (push value (storage stack)))
	stack)
